package com.zb.mobile.network.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.zb.entity.*;
import com.zb.extend.WithdrawExtend;
import com.zb.extend.WorkOrderExtend;
import com.zb.finance.service.ConWithdrawService;
import com.zb.mobile.*;
import com.zb.mobile.network.service.ConNetworkMobileWithdrawService;
import com.zb.result.PageUtil;
import com.zb.service.*;
import com.zb.view.ViewNetworkEmpAccount;
import com.zb.vo.OrderSettlementPriceVo;
import com.zb.vo.WithdrawVo;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Author WEN
 * @Date 2024/5/25 0025
 **/
@Service
public class ConNetworkMobileWithdrawServiceImpl implements ConNetworkMobileWithdrawService {
    @Resource
    private ZjWorkOrderService workOrderService;
    @Resource
    private ConWithdrawService conWithdrawService;
    @Resource
    private ZjWithdrawService withdrawService;
    @Resource
    private ViewNetworkEmpAccountService viewNetworkEmpAccountService;
    @Resource
    private ZjNetworkStrategyService networkStrategyService;
    @Resource
    private ZjNetworkEmpRelationService networkEmpRelationService;

    // 获取提现账户金额
    @Override
    public Object getWithdrawMoney(AccounLoginInfo loginInfo) {
        ZjNetworkEmpRelation empRelation = networkEmpRelationService.getNetworkEmpIdAndNetworkId(loginInfo.getNetworkEmpId(), loginInfo.getNetworkId());
        Long networkEmpId = loginInfo.getNetworkEmpId();
        if (empRelation.getManager()) {
            ZjNetworkStrategy strategy = networkStrategyService.getById(loginInfo.getNetworkId());
            if (strategy.getAllowManagerHelpWithdraw()) {
                networkEmpId = null;
            }
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("withdrawMoney", workOrderService.getNetworkWithdrawMoney(loginInfo.getNetworkId(), networkEmpId)); // 可提现金额
        resultMap.put("freezeMoney", workOrderService.getNetworkFreezeMoney(loginInfo.getNetworkId(), networkEmpId)); // 冻结金额
        resultMap.put("applyWithdrawMoney", withdrawService.getApplyWithdrawMoney(loginInfo.getNetworkId(), networkEmpId)); // 申请提现金额
        resultMap.put("totalWithdrawMoney", withdrawService.getTotalWithdrawMoney(loginInfo.getNetworkId(), networkEmpId)); // 累计提现金额
        return resultMap;
    }

    // 获取工单记录
    @Override
    public Map<String, Object> getMobileWithdrawOrderRecord(AccounLoginInfo loginInfo, NetworkOrderRecordSearchVo search) {
        if (null == search.getStatus()) {
            search.setStatus(1);
        }
        PageUtil.setPageLimitMobile(search);
        long count = workOrderService.getMobileWithdrawOrderRecordCount(loginInfo.getNetworkId(), loginInfo.getNetworkEmpId(), search);
        if (count <= 0) {
            return PageUtil.pageList(search.getPage(), search.getLimit(), count, new ArrayList<>());
        }
        List<ZjWorkOrder> orderList = workOrderService.getMobileWithdrawOrderRecord(loginInfo.getNetworkId(), loginInfo.getNetworkEmpId(), search);
        if (search.getStatus() == 2) {
            return PageUtil.pageList(search.getPage(), search.getLimit(), count, orderList.stream().map(order -> {
                NetworkOrderRecordListVo vo = new NetworkOrderRecordListVo();
                vo.setId(order.getId());
                vo.setWorkNo(order.getCode());
                vo.setDateTime(order.getGmtCreate());
                return vo;
            }).toList());
        }
        // 查询服务费、配件费
        List<QtyVo> fees = workOrderService.getNetworkTotalFee(orderList.stream().map(ZjWorkOrder::getId).toList());
        return PageUtil.pageList(search.getPage(), search.getLimit(), count, orderList.stream().map(order -> {
            NetworkOrderRecordListVo vo = new NetworkOrderRecordListVo();
            vo.setId(order.getId());
            vo.setWorkNo(order.getCode());
            vo.setDateTime(DateUtils.addDays(order.getEndTime(), order.getWithdrawFreezeDay()));
            vo.setStatus(vo.getDateTime().after(new Date())? 1 : 2); // 1-冻结中，2-已解冻
            vo.setTotalPrice(order.getNetworkModulePrice().add(fees.stream().filter(f -> Objects.equals(f.getId(), order.getId())).map(QtyVo::getPrice).findFirst().orElse(new BigDecimal("0.0"))));
            return vo;
        }).toList());
    }

    // 获取工单记录详情
    @Override
    public Object getWithdrawOrderRecordDetail(Long workId) {
        Map<String, Object> resultMap = new HashMap<>();
        ZjWorkOrder order = workOrderService.getWithdrawOrderRecordDetail(workId);
        QtyVo fee = workOrderService.getNetworkTotalFeeById(workId);
        resultMap.put("id", null == order? "" : order.getId());
        resultMap.put("workNo", null == order? "" : order.getCode());
        resultMap.put("endTime", null == order? "" : order.getEndTime());
        Date dateTime = null;
        Integer status = 1; // 默认状态：1-冻结中，2-已解冻
        if (null != order) {
            Date date = DateUtils.addDays(order.getEndTime(), order.getWithdrawFreezeDay());
            dateTime = date.after(new Date())? order.getEndTime() : date;
            status = date.after(new Date())? 1 : 2;
        }
        BigDecimal totalPrice = order.getNetworkModulePrice();
        if (null != fee) {
            totalPrice = totalPrice.add(fee.getPrice());
        }
        resultMap.put("dateTime", dateTime);
        resultMap.put("status", status);
        resultMap.put("totalPrice", totalPrice);
        return resultMap;
    }

    // 可提现工单列表
    @Override
    public Map<String, Object> getMobileWithdrawOrderList(AccounLoginInfo loginInfo, NetworkOrderRecordSearchVo search) {
        ZjNetworkEmpRelation empRelation = networkEmpRelationService.getByNetworkIdAndNetworkEmpId(loginInfo.getNetworkId(), loginInfo.getNetworkEmpId());
        Long networkEmpId = null;
        if (!empRelation.getManager() && !empRelation.getSuperManager()) {
            networkEmpId = loginInfo.getNetworkEmpId();
        }
        PageUtil.setPageLimitMobile(search);
        long count = workOrderService.getWithdrawOrderListCount(loginInfo.getNetworkId(), networkEmpId, search);
        if (count <= 0) {
            return PageUtil.pageList(search.getPage(), search.getLimit(), count, new ArrayList<>());
        }
        List<WorkOrderExtend> orderList = workOrderService.getWithdrawOrderList(loginInfo.getNetworkId(), networkEmpId, search);
        // 查询服务费、配件费
        List<OrderSettlementPriceVo> settlementPriceVoList = workOrderService.getOrderSettlementPriceByWorkId(orderList.stream().map(ZjWorkOrder::getId).toList());
//        List<QtyVo> fees = workOrderService.getNetworkTotalFee(orderList.stream().map(ZjWorkOrder::getId).toList());
        // 查询工程师
        List<ViewNetworkEmpAccount> networkEmpAccountList = viewNetworkEmpAccountService.getByIds(orderList.stream().map(WorkOrderExtend::getNetworkEmpId).distinct().toList());
        List<NetworkWithdrawOrderListVo> withdrawOrderListVoList = new ArrayList<>();
        NetworkWithdrawOrderListVo withdrawOrderListVo = null;
        ViewNetworkEmpAccount viewNetworkEmpAccount = null;
        for (WorkOrderExtend order : orderList) {
            withdrawOrderListVo = new NetworkWithdrawOrderListVo();
            withdrawOrderListVo.setId(order.getId());
            withdrawOrderListVo.setWorkNo(order.getCode());
            withdrawOrderListVo.setEndTime(order.getEndTime());
            withdrawOrderListVo.setTotalPrice(order.getNetworkModulePrice().add(settlementPriceVoList.stream().filter(f -> Objects.equals(f.getWorkId(), order.getId())).findFirst()
                    .map(OrderSettlementPriceVo::getPayNetworkPrice).orElse(new BigDecimal("0.0"))).subtract(order.getNetworkSettlementDeductionPrice()));
            withdrawOrderListVo.setUsername(order.getUserName());
            withdrawOrderListVo.setUsePhone(order.getUserPhone());
            withdrawOrderListVo.setEngineerId(order.getNetworkEmpId());
            viewNetworkEmpAccount = networkEmpAccountList.stream().filter(f -> Objects.equals(f.getId(), order.getNetworkEmpId())).findFirst().orElse(null);
            if (null != viewNetworkEmpAccount) {
                withdrawOrderListVo.setEngineer(viewNetworkEmpAccount.getName());
                withdrawOrderListVo.setEngineerPhone(viewNetworkEmpAccount.getPhone());
            }
            withdrawOrderListVoList.add(withdrawOrderListVo);
        }
        return PageUtil.pageList(search.getPage(), search.getLimit(), count, withdrawOrderListVoList);
    }

    // 保存移动端申请提现
    @Override
    public void saveMobileWithdraw(AccounLoginInfo loginInfo, WithdrawMobileVo withdrawMobileVo) {
        WithdrawVo withdrawVo = new WithdrawVo();
        BeanUtil.copyProperties(withdrawMobileVo, withdrawVo);
        withdrawVo.setApplyNetworkId(loginInfo.getNetworkId());
        withdrawVo.setApplyNetworkEmpId(loginInfo.getNetworkEmpId());
        withdrawVo.setApplyNetworkEmp(loginInfo.getName());
        conWithdrawService.save(loginInfo, withdrawVo);
    }

    // 获取提现记录列表
    @Override
    public Map<String, Object> getWithdrawRecordList(AccounLoginInfo loginInfo, WithdrawRecordListSearchMobileVo search) {
        PageUtil.setPageLimit(search);
        long count = withdrawService.getWithdrawRecordListCount(loginInfo.getNetworkId(), loginInfo.getNetworkEmpId(), search);
        if (count <= 0) {
            return PageUtil.pageList(search.getPage(), search.getLimit(), count, new ArrayList<>());
        }
        List<WithdrawExtend> extendList = withdrawService.getWithdrawRecordList(loginInfo.getNetworkId(), loginInfo.getNetworkEmpId(), search);
        return PageUtil.pageList(search.getPage(), search.getLimit(), count, extendList.stream().map(withdraw -> {
            WithdrawRecordListMobileVo vo = new WithdrawRecordListMobileVo();
            vo.setId(withdraw.getId());
            vo.setCode(withdraw.getCode());
            vo.setStatus(withdraw.getStatus());
            vo.setCreateTime(withdraw.getGmtCreate());
            vo.setReceivedAmount(withdraw.getReceivedAmount());
            vo.setBand(withdraw.getName());
            return vo;
        }).toList());
    }

    // 获取提现记录详情
    @Override
    public WithdrawRecordDetailMobileVo getWithdrawRecordDetail(Long id) {
        ZjWithdraw withdraw = withdrawService.getById(id);
        Assert.notNull(withdraw, "查无此提现单：" + id);
        WithdrawRecordDetailMobileVo vo = new WithdrawRecordDetailMobileVo();
        BeanUtil.copyProperties(withdraw, vo);
        vo.setCreateTime(withdraw.getGmtCreate());
        return vo;
    }

    // 根据提现单ID获取提现工单
    @Override
    public Object getWithdrawOrderList(Long id) {
        return conWithdrawService.getWithdrawOrder(id);
    }
}
